import { cloneDeep } from "lodash-es";
import type { Ref } from "vue";
import type { Point } from "/@/components/types";
import { useDrag } from "/@/hooks/useDrag";
import { getRotatePoint } from "/@/utils/draw";
import moveP0 from "./moveP0";
import moveP1 from "./moveP1";
import moveP2 from "./moveP2";
import moveP3 from "./moveP3";
import moveP4 from "./moveP4";
import moveP5 from "./moveP5";
import moveP6 from "./moveP6";
import moveP7 from "./moveP7";
const movePointHandlers = {
  0: moveP0,
  1: moveP1,
  2: moveP2,
  3: moveP3,
  4: moveP4,
  5: moveP5,
  6: moveP6,
  7: moveP7,
};

/**
 * 0----1----2
 * |         |
 * 7         3
 * |         |
 * 6----5----4
 */
type StartResult = {
  width: number;
  height: number;
  //points深拷贝后的数组
  points: Point[];
  //points中的点旋转后组成的数组
  rotatePoints: Point[];
  //直线p1p5的方程数据，为null说明垂直于x轴
  lineP1P5: { k: number; b: number } | null;
  //直线p3p7的方程数据，为null说明垂直于x轴
  lineP3P7: { k: number; b: number } | null;
} & Point;

export interface MovePointOptions {
  rotatePoints: Point[];
  newPoint: Point;
  rotate: number;
  lineP1P5: StartResult["lineP1P5"];
  lineP3P7: StartResult["lineP3P7"];
  width: number;
  height: number;
}

export interface MovePointResult {
  newX?: number;
  newY?: number;
  newWidth?: number;
  newHeight?: number;
}

export function useRectDrag({
  element,
  x,
  y,
  width,
  height,
  points,
  rotate,
  move,
}: {
  element: HTMLDivElement | undefined;
  x: Ref<number>;
  y: Ref<number>;
  width: Ref<number>;
  height: Ref<number>;
  points: Ref<Point[]>;
  rotate: Ref<number>;
  move: () => void;
}) {
  if (!element) {
    return {
      rectDragStart: undefined,
    };
  }

  const { dragStart: rectDragStart } = useDrag<[number], StartResult>({
    element,
    start() {
      const clonePoints = cloneDeep(points.value);
      const rotatePoints = clonePoints.map((p1) => {
        return getRotatePoint(
          {
            x: clonePoints[1].x,
            y: clonePoints[3].y,
          },
          p1,
          rotate.value
        );
      });
      let lineP1P5: StartResult["lineP1P5"] = null;
      if (rotatePoints[1].x !== rotatePoints[5].x) {
        const k = (rotatePoints[1].y - rotatePoints[5].y) / (rotatePoints[1].x - rotatePoints[5].x);
        const b = rotatePoints[1].y - k * rotatePoints[1].x;
        lineP1P5 = {
          k,
          b,
        };
      }
      let lineP3P7: StartResult["lineP3P7"] = null;
      if (rotatePoints[3].x !== rotatePoints[7].x) {
        const k = (rotatePoints[3].y - rotatePoints[7].y) / (rotatePoints[3].x - rotatePoints[7].x);
        const b = rotatePoints[3].y - k * rotatePoints[3].x;
        lineP3P7 = {
          k,
          b,
        };
      }
      return {
        x: x.value,
        y: y.value,
        width: width.value,
        height: height.value,
        points: clonePoints,
        rotatePoints,
        lineP1P5,
        lineP3P7,
      };
    },
    move({ dx, dy, startData, startResult }) {
      const index = startData.args[0];
      const rotatePoints = startResult.rotatePoints;
      //当前拖动的点 拖动后的实际坐标
      const newPoint = { x: rotatePoints[index].x + dx, y: rotatePoints[index].y + dy };
      const moveOptions: MovePointOptions = {
        rotatePoints,
        newPoint,
        rotate: rotate.value,
        lineP1P5: startResult.lineP1P5,
        lineP3P7: startResult.lineP3P7,
        width: startResult.width,
        height: startResult.height,
      };
      let moveResult: MovePointResult | null = null;
      const moveHandler = movePointHandlers[index];
      if (moveHandler) {
        moveResult = moveHandler(moveOptions);
      }
      if (moveResult) {
        moveResult.newX !== undefined && (x.value = moveResult.newX);
        moveResult.newY !== undefined && (y.value = moveResult.newY);
        moveResult.newWidth !== undefined && (width.value = moveResult.newWidth);
        moveResult.newHeight !== undefined && (height.value = moveResult.newHeight);
      }
      move();
    },
  });
  return {
    rectDragStart,
  };
}
